package edu.ivanov.apm.quant;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * User: Илья
 * Date: 06.10.13
 * Time: 18:21
 */
public class ParametersReader {

	private enum ParameterSetter {
		m("массы частицы") {

			public void setParameter(double value, Solver solver) {
				solver.setM(value);
			}
		},
		l("модуля значений границ потенциальной ямы") {

			public void setParameter(double value, Solver solver) {
				solver.setL(value);
			}
		},
		v0("амплитуды функции U(x)") {

			public void setParameter(double value, Solver solver) {
				solver.setV0(value);
			}
		},
		n("количества узлов сетки", true) {

			public void setParameter(int value, Solver solver) {
				solver.setN(value);
			}
		},
		u_min("минимума функции U(x) на отрезке [-L, L]") {

			public void setParameter(double value, Solver solver) {
				solver.setUMin(value);
			}
		},
		eps("точности пристрелки") {

			public void setParameter(double value, Solver solver) {
				solver.setEps(value);
			}
		},
		i("номера последнего квантовомеханического состояния", true) {

			public void setParameter(int value, Solver solver) {
				solver.setI(value);
			}
		};

		private String description;
		private boolean integer;

		private ParameterSetter(String description, boolean integer) {
			this.description = description;
			this.integer = integer;
		}

		private ParameterSetter(String description) {
			this(description, false);
		}

		public String getDescription() {
			return description;
		}

		public boolean isInteger() {
			return integer;
		}

		public void setParameter(double value, Solver solver) {}

		public void setParameter(int value, Solver solver) {}
	}

	/**
	 * Читает параметры из файла в формате Java-properties.
	 *
	 * @param filePath Путь файла для чтения.
	 */
	public void readFromFile(String filePath, Solver solver) throws IOException, ParametersException {
		if (filePath == null || solver == null)
			return;

		Properties properties = new Properties();
		properties.load(new FileInputStream(filePath));

		for (ParameterSetter setter : ParameterSetter.values()) {
			String rawValue = properties.getProperty(setter.name());
			if (rawValue == null)
				throw new ParametersException(String.format("Не задано значение %s (параметр %s)", setter.getDescription(), setter.name()));

			Object value;
			try {
				if (setter.isInteger())
					value = Integer.valueOf(rawValue);
				else
					value = Double.valueOf(rawValue);
			} catch (NumberFormatException e) {
				throw new ParametersException(String.format("Значение %s некорректно (параметр %s)", setter.getDescription(), setter.name()));
			}

			if (setter.isInteger())
				setter.setParameter((Integer) value, solver);
			else
				setter.setParameter((Double) value, solver);
		}
	}

	public static class ParametersException extends Exception {

		public ParametersException(String message) {
			super(message);
		}
	}
}
